package net.dodoman.notepad;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.print.PrinterJob;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.undo.UndoManager;

class MainWindow extends JFrame implements ActionListener, KeyListener,
		MouseListener, UndoableEditListener, WindowListener {
	/**
	 * 
	 */
	private static final long serialVersionUID = 2229243122390175139L;
	JMenuBar menuBar;
	JMenu file, edit, see, database, face, help;
	JMenuItem new1, open, save, exit, redo, undo, cut, copy, paste, selectAll,
			newline, metal, motif, windows, helpContent, about, redoPopup,
			undoPopup, cutPopup, copyPopup, pastePopup, selectAllPopup,
			dConection, print, timeDate, find;
	ActionAbout dialog;
	JCheckBoxMenuItem toolBar;
	JToolBar bar;
	JTextArea text;
	JScrollPane scroll;
	MainWindow exitWindow;
	JFileChooser chooser;
	BufferedReader in;
	PrintWriter write;
	JButton bnew, bopen, bsave, bexit, bredo, bundo, bcut, bcopy, bpaste,
			bselectAll, bhelp, babout, bprint, bfind;
	String metalFace, motifFace, windowsFace;
	boolean textAction = false; // 定义记录文本区第一次按下的行为,实现窗口关闭时,提示用户保存文件
	UndoManager undoManger;// 定义出undo/ redo对象
	JPopupMenu textPopup;
	PrintRequestAttributeSet attributes;

	MainWindow() {
		setTitle("JAVA Word文档编辑器");
		setExtendedState(JFrame.MAXIMIZED_BOTH);
		setSize(700, 500);
		setLayout(new BorderLayout());
		// 设置窗口响应事件
		this.addWindowListener(this);
		text = new JTextArea();
		// text = new JTextPane();
		scroll = new JScrollPane(text);
		getContentPane().add(scroll, BorderLayout.CENTER);
		// 设置文本区响应事件
		text.addMouseListener(this);
		text.addKeyListener(this);
		// 设置菜单栏
		menuBar = new JMenuBar();
		setJMenuBar(menuBar);
		// 设置文件菜单
		file = new JMenu("文件(F)");
		file.setMnemonic('F');
		menuBar.add(file);
		new1 = new JMenuItem("新建", new ImageIcon("/resources/AlertNew.ico"));
		new1.setHorizontalTextPosition(SwingConstants.RIGHT);
		new1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,
				InputEvent.CTRL_MASK));
		open = new JMenuItem("打开", new ImageIcon("ico/open16.gif"));
		open.setHorizontalTextPosition(SwingConstants.RIGHT);
		open.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,
				InputEvent.CTRL_MASK));
		save = new JMenuItem("保存", new ImageIcon("ico/save16.gif"));
		save.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
				InputEvent.CTRL_MASK));
		print = new JMenuItem("打印", new ImageIcon("ico/print16.gif"));
		print.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P,
				InputEvent.CTRL_MASK));
		exit = new JMenuItem("退出", new ImageIcon("ico/exit.gif"));
		exit.setHorizontalTextPosition(SwingConstants.RIGHT);
		exit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
				InputEvent.CTRL_MASK));
		file.add(new1);
		file.add(open);
		file.add(save);
		file.addSeparator();
		file.add(print);
		file.addSeparator();
		file.add(exit);
		// 增加文件菜单事件响应
		new1.addActionListener(this);
		open.addActionListener(this);
		save.addActionListener(this);
		print.addActionListener(this);
		exit.addActionListener(this);
		// 设置编辑菜单
		edit = new JMenu("编辑(E)");
		edit.setMnemonic('E');
		menuBar.add(edit);
		redo = new JMenuItem("重复", new ImageIcon("ico/redo16.gif"));
		redo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R,
				InputEvent.CTRL_MASK));
		undo = new JMenuItem("撤消", new ImageIcon("ico/undo16.gif"));
		undo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z,
				InputEvent.CTRL_MASK));
		cut = new JMenuItem("剪贴", new ImageIcon("ico/cut16.gif"));
		cut.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,
				InputEvent.CTRL_MASK));
		copy = new JMenuItem("复制", new ImageIcon("ico/copy16.gif"));
		copy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,
				InputEvent.CTRL_MASK));
		paste = new JMenuItem("粘贴", new ImageIcon("ico/paste16.gif"));
		paste.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V,
				InputEvent.CTRL_MASK));
		timeDate = new JMenuItem("插入日期时间", new ImageIcon("ico/date.gif"));
		timeDate.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T,
				InputEvent.CTRL_MASK));
		find = new JMenuItem("查找/替换", new ImageIcon("ico/find16.gif"));
		find.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F,
				InputEvent.CTRL_MASK));
		selectAll = new JMenuItem("全选", new ImageIcon("ico/selectAll.gif"));
		selectAll.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A,
				InputEvent.CTRL_MASK));
		edit.add(redo);
		edit.add(undo);
		edit.add(cut);
		edit.add(copy);
		edit.add(paste);
		edit.add(timeDate);
		edit.add(find);
		edit.add(selectAll);
		// 增加编辑菜单事件响应
		redo.addActionListener(this);
		undo.addActionListener(this);
		cut.addActionListener(this);
		copy.addActionListener(this);
		paste.addActionListener(this);
		selectAll.addActionListener(this);
		timeDate.addActionListener(this);
		find.addActionListener(this);
		// 设置查看菜单
		see = new JMenu("查看(V)");
		see.setMnemonic('V');
		newline = new JMenuItem("自动换行");
		toolBar = new JCheckBoxMenuItem("是否隐藏工具栏");
		toolBar.setSelected(true);
		menuBar.add(see);
		see.add(newline);
		see.add(toolBar);
		// 增加工具事件响应
		newline.addActionListener(this);
		toolBar.addActionListener(this);
		// 设置查询数据库菜单
		database = new JMenu("查询数据库(D)");
		database.setMnemonic('D');
		dConection = new JMenuItem("连接数据库", new ImageIcon("ico/cserver.gif"));
		menuBar.add(database);
		database.add(dConection);
		// 增加查询数据库菜单事件响应
		dConection.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Database db = new Database(MainWindow.this);
				db.setVisible(true);
			}
		});
		// 设置外观
		face = new JMenu("外观设置(A)");
		face.setMnemonic('A');
		metal = new JMenuItem("JAVA 外观", new ImageIcon("ico/metal-Inform.gif"));
		motif = new JMenuItem("UNIX 外观", new ImageIcon("ico/metal-Inform.gif"));
		windows = new JMenuItem("Windows 外观", new ImageIcon(
				"ico/metal-Inform.gif"));
		menuBar.add(face);
		face.add(metal);
		face.add(motif);
		face.add(windows);
		// 增加外观事件响应
		metal.addActionListener(this);
		motif.addActionListener(this);
		windows.addActionListener(this);
		// 设置帮助菜单
		help = new JMenu("帮助(H)");
		help.setMnemonic('H');
		menuBar.add(help);
		helpContent = new JMenuItem("帮助内容(H)");
		helpContent.setMnemonic('H');
		helpContent.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0)); // 快捷键为F1,其中的"0"代表不使用控制键
		helpContent.setIcon(new ImageIcon("ico/help16.gif"));
		helpContent.addActionListener(this);
		about = new JMenuItem("关于", new ImageIcon("ico/About16.gif"));
		help.add(helpContent);
		help.add(about);
		about.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				dialog = new ActionAbout(MainWindow.this);// 调用自定义关于对话框
				dialog.setVisible(true);
			}
		});
		// 工具栏上按钮定义
		bnew = new JButton(new ImageIcon("ico/new24.gif"));
		bopen = new JButton(new ImageIcon("ico/open24.gif"));
		bsave = new JButton(new ImageIcon("ico/save24.gif"));
		bprint = new JButton(new ImageIcon("ico/print24.gif"));
		bredo = new JButton(new ImageIcon("ico/Redo24.gif"));
		bundo = new JButton(new ImageIcon("ico/undo24.gif"));
		bcut = new JButton(new ImageIcon("ico/cut24.gif"));
		bcopy = new JButton(new ImageIcon("ico/copy24.gif"));
		bpaste = new JButton(new ImageIcon("ico/paste24.gif"));
		bfind = new JButton(new ImageIcon("ico/Find24.gif"));
		bselectAll = new JButton(new ImageIcon("ico/selectAll.gif"));
		bhelp = new JButton(new ImageIcon("ico/Help24.gif"));
		bexit = new JButton(new ImageIcon("ico/shutdown.gif"));
		// 设置提示文本
		bnew.setToolTipText("新建");
		bopen.setToolTipText("打开");
		bsave.setToolTipText("保存");
		bredo.setToolTipText("重复");
		bundo.setToolTipText("撤消");
		bcut.setToolTipText("剪贴");
		bcopy.setToolTipText("复制");
		bpaste.setToolTipText("粘贴");
		bfind.setToolTipText("查找/替换");
		bselectAll.setToolTipText("全选");
		bhelp.setToolTipText("帮助");
		bprint.setToolTipText("打印");
		bexit.setToolTipText("退出");
		bar = new JToolBar();
		getContentPane().add(bar, BorderLayout.NORTH);
		bar.add(bnew);
		bar.add(bopen);
		bar.add(bsave);
		bar.add(bprint);
		bar.addSeparator();
		bar.add(bredo);
		bar.add(bundo);
		bar.add(bcut);
		bar.add(bcopy);
		bar.add(bpaste);
		bar.add(bfind);
		// bar.add(bselectAll);
		bar.addSeparator();
		bar.add(bhelp);
		bar.addSeparator();
		bar.add(bexit);
		// 增加工具栏按钮事件
		bnew.addActionListener(this);
		bopen.addActionListener(this);
		bsave.addActionListener(this);
		bredo.addActionListener(this);
		bundo.addActionListener(this);
		bcut.addActionListener(this);
		bcopy.addActionListener(this);
		bpaste.addActionListener(this);
		bfind.addActionListener(this);
		bselectAll.addActionListener(this);
		bhelp.addActionListener(this);
		bprint.addActionListener(this);
		bexit.addActionListener(this);
		// 设置弹出菜单
		textPopup = new JPopupMenu();
		// text.add(textPopup);
		redoPopup = new JMenuItem("重复", new ImageIcon("ico/redo.jpg"));
		redoPopup.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R,
				InputEvent.CTRL_MASK));
		undoPopup = new JMenuItem("撤消", new ImageIcon("ico/undo.jpg"));
		undoPopup.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z,
				InputEvent.CTRL_MASK));
		cutPopup = new JMenuItem("剪贴", new ImageIcon("ico/Cut16.gif"));
		cutPopup.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,
				InputEvent.CTRL_MASK));
		copyPopup = new JMenuItem("复制", new ImageIcon("ico/copy.gif"));
		copyPopup.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,
				InputEvent.CTRL_MASK));
		pastePopup = new JMenuItem("粘贴", new ImageIcon("ico/paste.gif"));
		pastePopup.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V,
				InputEvent.CTRL_MASK));
		selectAllPopup = new JMenuItem("全选", new ImageIcon("ico/selectAll.gif"));
		selectAllPopup.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A,
				InputEvent.CTRL_MASK));
		textPopup.add(redoPopup);
		textPopup.add(undoPopup);
		textPopup.addSeparator();
		textPopup.add(cutPopup);
		textPopup.add(copyPopup);
		textPopup.add(pastePopup);
		textPopup.addSeparator();
		textPopup.add(selectAllPopup);
		// 设置弹出菜单响应事件
		redoPopup.addActionListener(this);
		undoPopup.addActionListener(this);
		cutPopup.addActionListener(this);
		copyPopup.addActionListener(this);
		pastePopup.addActionListener(this);
		selectAllPopup.addActionListener(this);
		// 设置文件对话实例
		chooser = new JFileChooser();
		// 设置撤消、重复对象实例
		undoManger = new UndoManager();

		text.getDocument().addUndoableEditListener(this);
	}

	// 各主件的行为响应
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == new1 || e.getSource() == bnew) {
			if (true == textAction) {
				saveDialog();
				JavaWord.start();
			} else {
				JavaWord.start();
			}
		}
		if (e.getSource() == open || e.getSource() == bopen) {
			openDialog();
		}
		if (e.getSource() == save || e.getSource() == bsave) {
			saveDialog();
		}
		if (e.getSource() == print || e.getSource() == bprint) {
			try {
				attributes = new HashPrintRequestAttributeSet();
				PrinterJob job = PrinterJob.getPrinterJob();
				if (job.printDialog())
					job.print(attributes);
			} catch (Exception ex) {
				JOptionPane.showMessageDialog(MainWindow.this, e);
			}
		}
		if (e.getSource() == redo || e.getSource() == bredo
				|| e.getSource() == redoPopup) {
			undoManger.redo();
		}
		if (e.getSource() == undo || e.getSource() == bundo
				|| e.getSource() == undoPopup) {
			undoManger.undo();
		}
		if (e.getSource() == cut || e.getSource() == bcut
				|| e.getSource() == cutPopup) {
			text.cut();
		}
		if (e.getSource() == copy || e.getSource() == bcopy
				|| e.getSource() == copyPopup) {
			text.copy();
		}
		if (e.getSource() == paste || e.getSource() == bpaste
				|| e.getSource() == pastePopup) {
			text.paste();
		}
		if (e.getSource() == find || e.getSource() == bfind) {
			FindDialog dFind = new FindDialog(text, MainWindow.this);
			dFind.setVisible(true);
		}
		if (e.getSource() == timeDate) {
			SimpleDateFormat dateFormat = new SimpleDateFormat(
					"yyyy'年'MM'月'dd'日'+HH:mm:ss");
			Calendar today = Calendar.getInstance();
			String timeDate = dateFormat.format(today.getTime());
			text.append(timeDate);
		}
		if (e.getSource() == selectAll || e.getSource() == bselectAll
				|| e.getSource() == selectAllPopup) {
			text.selectAll();
		}
		if (e.getSource() == newline) {
			text.setLineWrap(true);
		}
		if (e.getSource() == toolBar) {
			if (toolBar.isSelected())
				bar.setVisible(true);
			else
				bar.setVisible(false);
		}
		if (e.getSource() == helpContent || e.getSource() == bhelp) {
			Runtime currentRunTime = Runtime.getRuntime();
			Process newProcess = null;
			try { // c:\winnt\hh.exe 为*.chm帮助文件的启动文件
				newProcess = currentRunTime.exec("hh.exe JavaWord.chm");
			} catch (Exception ex) {
				JOptionPane.showMessageDialog(MainWindow.this,
						"不能正确地加载帮助文件，请检查您的c:\\winnt\\hh.exe文件是否存在", "打开文件",
						JOptionPane.ERROR_MESSAGE);
				ex.printStackTrace();
			}
		}
		if (e.getSource() == exit || e.getSource() == bexit) {
			if (true == textAction) {
				saveDialog();
				setVisible(false);
				shutWindow();
			} else {
				setVisible(false);
				shutWindow();
			}

		}
		if (e.getSource() == metal) {
			setFace("javax.swing.plaf.metal.MetalLookAndFeel");
		}
		if (e.getSource() == motif) {
			setFace("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
		}
		if (e.getSource() == windows) {
			setFace("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
		}
	}// 各主件的行为响应完毕

	// 外观设置
	public void setFace(String plaf) {
		try {
			UIManager.setLookAndFeel(plaf);
			SwingUtilities.updateComponentTreeUI(this);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	// 打开对话框
	public void openDialog() {
		chooser.setCurrentDirectory(new File("."));
		// 文件过滤
		chooser.setFileFilter(new FileFilter() {
			public boolean accept(File f) {
				String fileName = f.getName().toLowerCase();
				return fileName.endsWith(".txt") || f.isDirectory();
			}

			public String getDescription() {
				return "Text Files";
			}
		});
		int openResult = chooser.showOpenDialog(MainWindow.this);
		if (openResult == JFileChooser.APPROVE_OPTION) {
			text.setText("");
			try {
				in = new BufferedReader(new FileReader(chooser
						.getSelectedFile().getPath()));
				String line;
				while ((line = in.readLine()) != null) {
					text.append(line);
					text.append("\n");
					text.validate();
				}
			} catch (Exception e) {
				JOptionPane.showMessageDialog(MainWindow.this, "文件不能打开",
						"打开文件", JOptionPane.ERROR_MESSAGE);
				e.printStackTrace();
			}
		} else {
			JOptionPane.showMessageDialog(MainWindow.this, "请用户选择需要打开的文件",
					"打开文件", JOptionPane.WARNING_MESSAGE);
		}
	} // 打开对话框完毕

	// 保存对话框
	public void saveDialog() {
		chooser.setCurrentDirectory(new File("."));
		// 文件过滤
		chooser.setFileFilter(new FileFilter() {
			public boolean accept(File f) {
				String fileName = f.getName().toLowerCase();
				return fileName.endsWith(".txt") || f.isDirectory();
			}

			public String getDescription() {
				return "Text Files";
			}
		});
		int saveResult = chooser.showSaveDialog(MainWindow.this);
		if (saveResult == JFileChooser.APPROVE_OPTION) {
			try {
				write = new PrintWriter(new FileOutputStream(chooser
						.getSelectedFile().getName()), true);
				write.println(text.getText());
			} catch (Exception e) {
				JOptionPane.showMessageDialog(MainWindow.this, "文件不能保存",
						"保存文件", JOptionPane.ERROR_MESSAGE);
				e.printStackTrace();
			}
		} else {
			JOptionPane.showMessageDialog(MainWindow.this, "请用户保存需要的文件",
					"保存文件", JOptionPane.WARNING_MESSAGE);
		}
	}// 保存对话框完毕

	public void shutWindow() {
		System.gc();
	}

	public void keyTyped(KeyEvent e) {
	}

	public void keyPressed(KeyEvent e) {
		textAction = true;
	}

	public void keyReleased(KeyEvent e) {
	}

	public void mouseClicked(MouseEvent e) {
	}

	public void mousePressed(MouseEvent me) {
		if (me.isPopupTrigger()) {
			textPopup.show(text, me.getX(), me.getY());
		}
	}

	public void mouseReleased(MouseEvent me) {
		if (me.isPopupTrigger()) {
			textPopup.show(text, me.getX(), me.getY());
		}
	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	// undo redo 判断是否可用
	public void undoableEditHappened(UndoableEditEvent parm1) {
		undoManger.addEdit(parm1.getEdit());
		// System.out.println(uedit);
		/*
		 * if (undoManger.canUndo()) { undo.setEnabled(true);
		 * bredo.setEnabled(true); // undoPopupItem.setEnabled(true); } else {
		 * undo.setEnabled(false); bundo.setEnabled(false); //
		 * undoPopupItem.setEnabled(false); } if (undoManger.canRedo()) {
		 * redo.setEnabled(true); bredo.setEnabled(true); //
		 * redoPopupItem.setEnabled(true); } else { redo.setEnabled(false);
		 * bredo.setEnabled(false); // redoPopupItem.setEnabled(false); }
		 */
	}

	public void windowOpened(WindowEvent e) {
		scroll.setFocusable(true);
	}

	public void windowClosing(WindowEvent e) {
		if (true == textAction) {
			saveDialog();
			setVisible(false);
		}
	}

	public void windowClosed(WindowEvent e) {
	}

	public void windowIconified(WindowEvent e) {
	}

	public void windowDeiconified(WindowEvent e) {
	}

	public void windowActivated(WindowEvent e) {
	}

	public void windowDeactivated(WindowEvent e) {
	}
}
